﻿#include "APIBridgeCom.h"
#include "utils/String/hexbin.h"
#include "services/tlv/Com/TlvThreadCom.h"
#include "components/HugeMsgPanel/HugeMsgPanel.h"
#include "components/Toast/Toast.h"

#include <QDebug>
#include <QJsonDocument>
#include <QJsonObject>
#include <QFileDialog>

#define RUNNER_NAME "TlvTool_APIBridgeCom"

APIBridgeCom::APIBridgeCom(QObject *parent)
    : IPCCom(RUNNER_NAME, parent)
{
    connect(TlvThreadCom::instance(), &TlvThreadCom::dataReceived, this, [=](const Tlv& tlv){
        if (!isOpen()) return;
        if (tlv.isIicFeedback()) {
            send(makeJsonIIC(IIC::fromTlv(tlv)));
        } else {
            send(makeJsonTlv(tlv));
        }
    });
}

void APIBridgeCom::onDataReceived(const QByteArray &data)
{
    QJsonParseError err;
    QJsonDocument doc = QJsonDocument::fromJson(data, &err);
    if (err.error != QJsonParseError::NoError) {
        return;
    }
    // 判断类型
    if (!doc.isObject()) {
        return;
    }
    QJsonObject obj = doc.object();
    int cmd = obj["cmd"].toInt();
    switch (cmd) {
    case CMD_SendTlv:
        handleSendTlv(obj["tag"].toString(), obj["value"].toString());
        break;
    case CMD_SendIIC:
        handleSendIIC(obj["addr"].toString(), obj["data"].toString(), obj["readlen"].toString());
        break;
    case CMD_ShowMsg:
        handleShowMsg(obj["msg"].toString(), obj["fontsize"].toInt());
        break;
    case CMD_ToastInfo:
        handleToastInfo(obj["msg"].toString(), obj["duration"].toInt());
        break;
    case CMD_ToastWarning:
        handleToastWarning(obj["msg"].toString(), obj["duration"].toInt());
        break;
    case CMD_ToastError:
        handleToastError(obj["msg"].toString(), obj["duration"].toInt());
        break;
    case CMD_ToastSuccess:
        handleToastSuccess(obj["msg"].toString(), obj["duration"].toInt());
        break;
    case CMD_SelectFile:
        handleSelectFile(obj["title"].toString());
        break;
    default:
        break;
    }
}

void APIBridgeCom::handleSendTlv(const QString &tag, const QString &value)
{
    Tlv tlv(static_cast<TlvTag>(tag.toUInt(nullptr, 16)), HexBin::parseHexString(value));
    TlvThreadCom::instance()->write(tlv);
}

void APIBridgeCom::handleSendIIC(const QString &addr, const QString &data, const QString &readlen)
{
    IIC iic(addr.toUInt(nullptr, 16), HexBin::parseHexString(data), readlen.toUInt());
    TlvThreadCom::instance()->write(iic);
}

void APIBridgeCom::handleShowMsg(const QString &msg, int fontsize)
{
    HugeMsgPanel::showMsg(msg, fontsize);
    send(makeJsonMsg(msg, fontsize));
}

void APIBridgeCom::handleToastInfo(const QString &msg, int duration)
{
    Toast::info(msg, duration);
    send(makeJsonToast(CMD_ToastInfo, msg, duration));
}

void APIBridgeCom::handleToastWarning(const QString &msg, int duration)
{
    Toast::warning(msg, duration);
    send(makeJsonToast(CMD_ToastWarning, msg, duration));
}

void APIBridgeCom::handleToastError(const QString &msg, int duration)
{
    Toast::error(msg, duration);
    send(makeJsonToast(CMD_ToastError, msg, duration));
}

void APIBridgeCom::handleToastSuccess(const QString &msg, int duration)
{
    Toast::success(msg, duration);
    send(makeJsonToast(CMD_ToastSuccess, msg, duration));
}

void APIBridgeCom::handleSelectFile(const QString& title)
{
    send("tick");  // 发送心跳包防止nodejs判定为超时而结束脚本
    QString filepath = QFileDialog::getOpenFileName(nullptr, title);
    send(makeJsonFile(filepath));
}

QByteArray APIBridgeCom::makeJsonTlv(const Tlv &tlv)
{
    QString res = QString(R"({"cmd":%1,"tag":"%2","value":"%3"})").arg(CMD_SendTlv)
                      .arg(static_cast<int>(tlv.tag()))
                      .arg(QString(tlv.value().toBase64()));
    return res.toUtf8();
}

QByteArray APIBridgeCom::makeJsonIIC(const IIC &iic)
{
    QString res = QString(R"({"cmd":%1,"status":"%2","data":"%3"})").arg(CMD_SendIIC)
                      .arg(static_cast<int>(iic.status()))
                      .arg(QString(iic.data().toBase64()));
    return res.toUtf8();
}

QByteArray APIBridgeCom::makeJsonMsg(const QString &msg, int fontsize)
{
    QString res = QString(R"({"cmd":%1,"msg":"%2","fontsize":%3})").arg(CMD_ShowMsg).arg(msg).arg(fontsize);
    return res.toUtf8();
}

QByteArray APIBridgeCom::makeJsonToast(uint8_t toastID, const QString &msg, int duration)
{
    QString res = QString(R"({"cmd":%1,"msg":"%2","duration":%3})").arg(toastID).arg(msg).arg(duration);
    return res.toUtf8();
}

QByteArray APIBridgeCom::makeJsonFile(const QString &filepath)
{
    QString res = QString(R"({"cmd":%1,"filepath":"%2"})").arg(CMD_SelectFile).arg(filepath);
    return res.toUtf8();
}

